var jsPath = "/js";
var classPath = jsPath + "/classes";

/**
 * @author mars
 * 
 * this file depends on prototype.js
 */
function parseInt2(num){
	var i = parseInt(num);
	i = i?i:0;
	return i;
}
/**
 * get an event instance between browser difference
 * @param Event event
 * @return Object
 */
function $E(event){
	return event || window.event;
}

/**
 * json string to json object
 * @param String json
 */
function $J(json){
	return Try.these(function (){return eval("("+json+")");},
					 function (){return null;});
}


/**
 * make a piece of HTML string to a DOMElement
 * 
 * @param String domText
 * @return DOMElement
 */
function $D(domText){
	var tempDom = document.createElement("div");
	tempDom.innerHTML = domText;
	var returnValue = tempDom.childNodes[0];
	tempDom = null;
	return $(returnValue);
}



/**
 * let the object become the event's propagation object
 * @param Object obj
 * @param Function func_name
 */
function _(obj, func_name){
	return function(event){
		obj[func_name].call(obj, event);
	};
}

function msgSuccess(holder, msg){
	$(holder).innerHTML = '<span class="success">'+msg+'</span>';
}

function msgFail(holder, msg){
	$(holder).innerHTML = '<span class="fail">'+msg+'</span>';
}

function GetCookie(sName)
{
  // cookies are separated by semicolons
  var aCookie = document.cookie.split("; ");
  for (var i=0; i < aCookie.length; i++)
  {
    // a name/value pair (a crumb) is separated by an equal sign
    var aCrumb = aCookie[i].split("=");
    if (sName == aCrumb[0]) 
      return unescape(aCrumb[1]);
  }

  // a cookie with the requested name does not exist
  return null;
}


Object.extend(String.prototype, {
	/**
	 * @author mars
	 * @method String.prototype.trim
	 * @return String
	 * @since 07-03-29
	 */
	trim: function(){
		return (this.replace(/^[\s\xA0]+/, "").replace(/[\s\xA0]+$/, ""));
  	},
	reverse: function(){
		var ret = '';
		for(var i=this.length-1; i>=0; i--){
			ret+= this[i];
		}
		return ret;
	},
	truncateCn: function(len, suffix){
		suffix = suffix?suffix:'...';
		var real_len = 0;
		for(var i=0; i<this.length; i++){
			real_len += (this.charCodeAt(i)>256)?2:1;
		}
		if(real_len<=len) return this;
		var current_len = 0;
		var ret = '';
		for(var i=0; i<len-suffix.length; i++){
			current_len += (this.charCodeAt(i)>256)?2:1;
			if(current_len<=len-suffix.length){
				ret += this.charAt(i);
			}else{
				break;
			}
		}
		
		return ret+suffix;
	},
	getLength: function(){
		var real_len = 0;
		for(var i=0; i<this.length; i++){
			real_len += (this.charCodeAt(i)>256)?2:1;
		}
		return real_len;
	},
	lineWrap: function(lineWidth){
		var real_len = 0;
		var ret = [];
		var start = 0;
		for(var i=0; i<this.length; i++){
			real_len += (this.charCodeAt(i)>256)?2:1;
			if(real_len>=lineWidth){
				ret.push(this.substring(start, i+1));
				start = i+1;
				real_len = 0;
			}
		}
		return ret.join("<br/>");
	}
});



var ScriptLoader = new Object();

Object.extend(ScriptLoader,
	{
		/**
		 * include a js file to the document after it was loaded
		 * @method ScriptLoader.include
		 * @param Array scripts
		 */
		include: function(scripts){
			if(!(scripts instanceof Array)){
				var scripts = $A(arguments);
			}
			for(var i = 0; i<scripts.length; i++){
				var jsDom = document.createElement("script");
				jsDom.src = scripts[i];
				document.getElementsByTagName("HEAD")[0].appendChild(jsDom);
			}
		},
		/**
		 * preload a js file to the document when it is loading
		 * @method ScriptLoader.preload
		 * @param {Object} scripts
		 */
		preload: function(scripts){
			if(!(scripts instanceof Array)){
				var scripts = $A(arguments);
			}
			for(var i = 0; i<scripts.length; i++){
				document.write("<script type='text/javascript' src='"+scripts[i]+"'></script>")
			}
		}
	}
);

var ClassLoader = new Object();
Object.extend(ClassLoader,
	{
		/**
		 * @method ClassLoader.include
		 */
		include: function(){
			var classes = $A(arguments);
			for(var i = 0; i<classes.length; i++){
				this.__checkPackage(classes[i]);
				classes[i] = classPath + "/" + classes[i].replace(/\./g, "/") + ".js";
			}
			ScriptLoader.include(classes);
		},
		/**
		 * @method ClassLoader.preload
		 */
		preload:function(){
			var classes = $A(arguments);
			for(var i = 0; i<classes.length; i++){
				this.__checkPackage(classes[i]);
				classes[i] = classPath + "/" + classes[i].replace(/\./g, "/") + ".js";
			}
			ScriptLoader.preload(classes);
		},
		/**
		 * check if the package exists, while not, create it
		 *  
		 * @method ClassLoader.__checkPackage
		 * @param String className
		 * @return Array
		 */
		__checkPackage:function(className){
			var pos = className.indexOf('.');
			do{
				var packageName = className.substr(0, pos);
				var expression = 'window.' + packageName + '==undefined';
				if(eval(expression)){
					expression = 'window.'+packageName+'= new Object();';
					eval(expression);
				}
			}while((pos = className.indexOf('.', pos+1))!=-1);
		}
	}
);

var CSSLoader = new Object();
Object.extend(CSSLoader,
	{
		/**
		 * @method CSSLoader.include
		 */
		include: function(){
			var css = $A(arguments);
			for(var i = 0; i<css.length; i++){
				if(document.createStyleSheet){
					document.createStyleSheet(css[i]);
				}else{
					var cssDom = document.createElement("style");
					cssDom.innerHTML = "@import '"+css[i]+"';";
					document.getElementsByTagName("HEAD")[0].appendChild(cssDom);
				}
			}
		}
	}
);

function nodeRemoveAll(node){
	for(var i=node.childNodes.length-1; i>=0; i--){
		node.removeChild(node.childNodes[i]);
	}
	return node;
}

function nodeAppendAll(node, nodes){
	for(var i=0; i<nodes.length; i++){
		node.appendChild(nodes[i]);
	}
	return node;
}

function createEmptyDOM(){
	if (document.implementation.createDocument){ 
		myDocument =document.implementation.createDocument("","",null); 
	} else if (window.ActiveXObject){ 
		// Internet Explorer, create a new XML document using ActiveX 
		// and use loadXML as a DOM parser. 
		myDocument = new ActiveXObject("Microsoft.XMLDOM");
	}
	return myDocument;
}

function parseXML(xmlString){
	if (document.implementation.createDocument){ 
		// Mozilla, create a new DOMParser 
		var parser = new DOMParser(); 
		myDocument = parser.parseFromString(xmlString, "text/xml"); 
	} else if (window.ActiveXObject){ 
		// Internet Explorer, create a new XML document using ActiveX 
		// and use loadXML as a DOM parser. 
		myDocument = new ActiveXObject("Microsoft.XMLDOM");
		myDocument.async="false"; 
		myDocument.loadXML(xmlString); 
	}
	return myDocument;
}
/*
function GetActiveText(objHTML) {
	if(document.selection){
		var obj=$(objHTML);
		obj.currPos = document.selection.createRange().duplicate()
	}
}
*/

function GetActiveText(event) {
	event = $E(event);
	var obj = Event.element(event);
	if(document.selection){
		obj.currPos = document.selection.createRange().duplicate();
	}
}


function InsertText(objHTML,strText,bolReplace) {
	if(strText==""){return("")}
	var obj=$(objHTML);
	
	if(document.selection){
		if (obj.currPos){
			if(bolReplace && (obj.value=="")){
				obj.currPos.text=strText
			}
			else{
				obj.currPos.text+=strText
			}
		}
		else{
			obj.value+=strText
		}
	}
	else{
		if(bolReplace){
			obj.value=obj.value.slice(0,obj.selectionStart) + strText + obj.value.slice(obj.selectionEnd,obj.value.length)
		}
		else{
			obj.value=obj.value.slice(0,obj.selectionStart) + strText + obj.value.slice(obj.selectionStart,obj.value.length)
		}
	}
	obj.focus();
}

function ReplaceText(objHTML,strPrevious,strNext) {
	var obj=$(objHTML);
	var strText;
	var doc = obj.ownerDocument;
	
	if(doc!=null && doc.selection && doc.selection.type == "Text"){
		if (obj.currPos){
			var range = doc.selection.createRange();
			range.text = strPrevious + range.text + strNext;
			return("");
		}
		else{
			strText=strPrevious + strNext;
			return(strText);
		}
	}
	else{
		if(obj.selectionStart || obj.selectionEnd){
			strText=strPrevious + obj.value.slice(obj.selectionStart,obj.selectionEnd) + strNext;
			return(strText);
		}
		else{
			strText=strPrevious + strNext;
			return(strText);
		}
	}
}

function createTag(tagName, tagPropertyJSON){
	var tag = document.createElement(tagName);
	return Object.extend(tag, tagPropertyJSON);
}

Object.extend(Element,{ 
	getPosition:function(element){
		element = $(element);
		
		if(element.offsetParent!=undefined && element.offsetParent!=null ){
			var parentPos = Element.getPosition(element.offsetParent);
			var left = element.offsetLeft;
			var top = element.offsetTop;
			
			//alert(element.tagName+":"+top);
			
			//alert(element.parentNode.tagName +":"+ element.parentNode.offsetTop);
			return {left: left + parentPos.left, top: top + parentPos.top};
		}else{
			return {left: element.offsetLeft, top: element.offsetTop};
		}
		
	}
});
/*
Object.extend(Element.prototype, {
	findAncestorTag: function(tagName){
		var ancestors = this.ancestors();
		for(var i=0; i<ancestors.length; i++){
			if(ancestors[i].tagName == tagName.toUpperCase()){
				return ancestors[i];
			}
		}
	}
});

*/

Object.extend(Element, {
	findAncestorTag: function(element,tagName){
		var ancestors = element.ancestors();
		for(var i=0; i<ancestors.length; i++){
			if(ancestors[i].tagName == tagName.toUpperCase()){
				return ancestors[i];
			}
		}
	}
});

Object.extend(Element, {
	getHTML: function(element){
		return element.xml || element.outerHTML;
	}
});

Object.extend(Element, {
	findAncestor: function(element,func){
		var ancestors = element.ancestors();
		return ancestors.find(func);
	}
});

Object.extend(Element, {
	isInViewPort: function(element){
		var pos = Element.getPosition(element);
		var dem = element.getDimensions();
		var top = document.documentElement.scrollTop;
		var bottom = top + document.documentElement.clientHeight;
		var left = document.documentElement.scrollLeft;
		var right = left + document.documentElement.clientWidth;
		
		return (pos.top > top) && (pos.top + dem.height < bottom) 
			&& (pos.left > left) && (pos.left + dem.width < right);
	}
});

Object.extend(Element, {
	disableSelection: function(element){
		element = $(element);
		if (typeof element.onselectstart!="undefined") //IE route
			element.onselectstart=function(){return false;};
		else if (typeof element.style.MozUserSelect!="undefined") //Firefox route
			element.style.MozUserSelect="none";
}});

Object.extend(Element, {
	copyHTMLElement:function (ele){
		if(document.all){
			return $D(ele.outerHTML);
		}else{
			return $D(ele.xml);
		}
}});

Object.extend(Event, {
	relatedElement: function(event){
		return event.toElement || event.relatedTarget;
	}
});

Object.extend(Number.prototype, {
	toHex: function(){
		var hexstring="0123456789abcdef";
		var value = this;
		var ret='';
		while(true){
			ret = hexstring.charAt(value%16) + ret;
			value = parseInt(value/16);
			if(value==0) return ret;
		}
	}
});

Object.extend(Number.prototype, {
	floatPos: function(pos){
		return parseInt((this*Math.pow(10, pos)).round())/Math.pow(10, pos);
	}
});

Object.extend(Number.prototype, {
	newTimeFormat: function(){
		var sec = 1000;
		var min = sec * 60;
		var hour = min * 60;
		var day = hour * 24;
		var month = day * 30;
		var year = month * 12;
		
		var txt = "以前";
		
		var now = new Date().getTime();
		var diff = now - this * 1000;
		
		var ret = '';
		var unit = '';
		var rule;
		if(diff >= year){
			rule = year;
			unit = '年';
		}else if(diff >= month){
			rule = month;
			unit = '月';
		}else if(diff >= day){
			rule = day;
			unit = '天';
		}else if(diff >= hour){
			rule = hour;
			unit = '小时';
		}else if(diff >= min){
			rule = min;
			unit = '分钟';
		}else{
			rule = sec;
			unit = '秒';
		}
		ret = parseInt(diff/rule) + unit + txt;
		
		if(diff<1000){
			ret = "1秒以前";
		}
		return ret;
	}
});

Object.extend(String.prototype, {
	fill: function(c, length){
		if(this.length>=length) 
			return this;
		else{
			return $R(0, length-this.length).map(function(value){ return c;}).join("") + this;
		}
			
	}
});
var isIE6  = (navigator.appVersion.indexOf("MSIE 6.0") != -1) ? true : false;
var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;

var MyPeriodicalExecuter = Class.create({
  currentTime: 0,
  initialize: function(interval_callback, complete_callback, frequency, runtimes) {
    this.callback = interval_callback;
    this.completeCallback = complete_callback;
    this.frequency = frequency;
    this.currentlyExecuting = false;
	this.runtimes = runtimes;

    this.registerCallback();
  },

  registerCallback: function() {
    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
  },

  execute: function() {
    this.callback(this);
	this.currentTime ++;
	if(this.runtimes!=null && this.currentTime >= this.runtimes){
		this.stop();
	}
  },

  stop: function() {
    if (!this.timer) return;
    clearInterval(this.timer);
    this.timer = null;
    
    if(this.completeCallback){
    	this.completeCallback(this);
    }
  },

  onTimerEvent: function() {
    if (!this.currentlyExecuting) {
      try {
        this.currentlyExecuting = true;
        this.execute();
      } finally {
        this.currentlyExecuting = false;
      }
    }
  }
});

/**
 * 只按宽度缩放，高度不限
 */
function resizeImgW(ImgD,iwidth){
	var img = new Image();
	img.src=ImgD.src;
	if(img.width>iwidth){
		ImgD.width=iwidth;
		ImgD.height=(img.height*iwidth)/img.width;
	}
	ImgD.alt=img.width+"×"+img.height;
}
function resizeImgH(ImgD,iheight){
	var img = new Image();
	img.src=ImgD.src;
	if(img.height>iheight){
		ImgD.height=iheight;
		ImgD.width=(img.width*iheight)/img.height;
	}
	ImgD.alt=img.width+"×"+img.height;
}
function resizeImg(ImgD,iwidth,iheight)
{
//参数(图片,允许的宽度,允许的高度)
	var image=new Image();
	image.src=ImgD.src;
	if(image.width>0 && image.height>0)
	{
		flag=true;
		if(image.width/image.height>= iwidth/iheight)
		{
			if(image.width>iwidth)
			{ 
				ImgD.width=iwidth;
				ImgD.height=(image.height*iwidth)/image.width;
			}
			else{
				ImgD.width=image.width; 
				ImgD.height=image.height;
			}
			ImgD.alt=image.width+"×"+image.height;
		}
		else{
			if(image.height>iheight){ 
				ImgD.height=iheight;
				ImgD.width=(image.width*iheight)/image.height; 
			}else{
				ImgD.width=image.width; 
				ImgD.height=image.height;
			}
		}
	}
}

// implement ff with outerHTML property
/*if(typeof(HTMLElement)!="undefined" && !window.opera) 
{ 
    HTMLElement.prototype.__defineGetter__("outerHTML",function() 
    { 
        var a=this.attributes, str="<"+this.tagName, i=0;for(;i<a.length;i++) 
        if(a[i].specified) 
            str+=" "+a[i].name+'="'+a[i].value+'"'; 
        if(!this.canHaveChildren) 
            return str+" />"; 
        return str+">"+this.innerHTML+"</"+this.tagName+">"; 
    }); 
    HTMLElement.prototype.__defineSetter__("outerHTML",function(s) 
    { 
        var r = this.ownerDocument.createRange(); 
        r.setStartBefore(this); 
        var df = r.createContextualFragment(s); 
        this.parentNode.replaceChild(df, this); 
        return s; 
    }); 
    HTMLElement.prototype.__defineGetter__("canHaveChildren",function() 
    { 
        return !/^(area|base|basefont|col|frame|hr|img|br|input|isindex|link|meta|param)$/.test(this.tagName.toLowerCase()); 
    }); 
} */

var dropDownMenu = Class.create();
dropDownMenu.prototype = {
	initialize:function(cls,delayDur,level){
		this.cls = cls;
		this.delayDur = delayDur || 1;
		this.delayID;
		this.subMenu;
		this.level = level || 1;
		this.init();
	},

	init:function(){
		$$(this.cls).each(function(o){
			o.observe("mouseover",function(e){
				if(this.subMenu){
					this.subMenu.hide();
				}
				if(this.delayID){
					window.clearTimeout(this.delayID);
				}
				this.subMenu = o.down(this.level);
				this.subMenu.show();
			}.bind(this));
			o.observe("mouseout",function(e){
				var _o = o.down(this.level);
				this.delayID = _o.hide.bind(_o).delay(this.delayDur);
			}.bind(this));
		}.bind(this));
	}
};